package it.univaq.di.helpdesk.presentation;

import it.univaq.di.helpdesk.business.common.DeviceService;
import it.univaq.di.helpdesk.business.common.FaqService;
import it.univaq.di.helpdesk.business.common.HelpDeskServiceFactory;
import it.univaq.di.helpdesk.business.common.OfficeService;
import it.univaq.di.helpdesk.business.common.TicketService;
import it.univaq.di.helpdesk.business.common.UserService;
import it.univaq.di.helpdesk.business.errors.IntegrityConstraintException;
import it.univaq.di.helpdesk.business.model.Category;
import it.univaq.di.helpdesk.business.model.Computer;
import it.univaq.di.helpdesk.business.model.Device;
import it.univaq.di.helpdesk.business.model.Faq;
import it.univaq.di.helpdesk.business.model.Hardware;
import it.univaq.di.helpdesk.business.model.Office;
import it.univaq.di.helpdesk.business.model.Software;
import it.univaq.di.helpdesk.business.model.User;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.MappingDispatchAction;

public class ManageDeviceAction extends MappingDispatchAction {

	/* AJAX Request */
	public ActionForward viewdevicehistory (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService serviceUser = factory.getUserService();
		OfficeService serviceOffice = factory.getOfficeService();
		
		List<String> devices = new ArrayList<String>(); 
		devices.add("Computer");
		devices.add("Printer");
		request.setAttribute("devices", devices);
		
		List<User> users = serviceUser.findAllUsers();
		request.setAttribute("users", users);
		
		List<Office> officeList = serviceOffice.findAllOffice();
		request.setAttribute("offices", officeList);
		
		return mapping.findForward("operator.viewdevicehistory");
	}
	

	/* AJAX Request */
	public ActionForward getdevicelist (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		UserService serviceUser = factory.getUserService();
		OfficeService serviceOffice = factory.getOfficeService();
		
		DeviceHistoryForm form = (DeviceHistoryForm) actionForm;
		
		Map<String, String> queryParam = new HashMap<String, String>();
		queryParam.put("type", form.getDeviceType());
		queryParam.put("user", form.getUserID());
		queryParam.put("office", form.getOfficeID());
		
		List<Device> devices = service.searchForDevice(queryParam);
		request.setAttribute("devices", devices);
		
		List<User> users = serviceUser.findAllUsers();
		request.setAttribute("users", users);
		
		List<Office> offices = serviceOffice.findAllOffice();
		request.setAttribute("offices", offices);
		
		return mapping.findForward("operator.getdevicelist");
	}
	
	/* AJAX Request */
	public ActionForward loadfeatures(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		
		int deviceID = Integer.parseInt(request.getParameter("itemID"));
		
		Device device = service.findDeviceById(deviceID);
		request.setAttribute("item", device);
		
		return mapping.findForward("operator.devicebox");
	}
	
	/* AJAX Request */
	public ActionForward deletedevice(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
			
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		
		int deviceID = Integer.parseInt(request.getParameter("deviceID"));
		
		boolean deviceAssigned = service.isDeviceAssigned(deviceID);
		
		if(! deviceAssigned ) {
			service.deleteDevice(deviceID);
			response.getWriter().print("{isDeviceAssigned:false}");
		} else {
			response.getWriter().print("{isDeviceAssigned:true}");
		}
		
		return null;
	}
	
	/* AJAX Request */
	public ActionForward changedeviceassigned(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		
		Map<String, String> mapassigned = new HashMap<String, String>();
		
		String deviceID = request.getParameter("deviceID");
		String user = request.getParameter("user");
		
		mapassigned.put("deviceid", deviceID);
		mapassigned.put("user", user);
		
		service.changeDeviceAssigned(mapassigned);

		return null;
	}
	
	/* AJAX Request */
	public ActionForward changedeviceassignedoffice(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		
		Map<String, String> mapassignedoffice = new HashMap<String, String>();
		
		String deviceID = request.getParameter("deviceID");
		String office = request.getParameter("office");
		
		mapassignedoffice.put("deviceid", deviceID);
		mapassignedoffice.put("office", office);
		
		service.changeDeviceAssignedOffice(mapassignedoffice);

		return null;
	}
	
	
	public ActionForward activeeditdevice(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		DeviceForm deviceForm = (DeviceForm) actionForm;
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		
		//recupero l'ID del device corrente
		int deviceID = Integer.parseInt(request.getParameter("deviceID"));
		Device device = service.getDeviceById(deviceID);
		
		BeanUtils.copyProperties(deviceForm, device);
		deviceForm.setDeviceType(device.getType());
		
		Computer computer = (Computer) device.getComposite();
		if (computer != null) {
			List<Device> hardware = new ArrayList<Device>();
			List<Device> software = new ArrayList<Device>();
			
			for (Device component : computer.getDevices()) {
				if ("Software".equals(component.getType())) {
					software.add(component);
				} else {
					hardware.add(component);
				}
			}
			
			deviceForm.setHardware(hardware);
			deviceForm.setSoftware(software);
		}
		
		// Salvataggio del token riutilizzato nel metodo editdevice.
		saveToken(request);
		
		return mapping.findForward("operator.activeeditdevice");
	}
	
	public ActionForward editdevice(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
	
		/* controlla se il token inserito in sessione dal metodo activeaddoffice
		 * è valido rispetto a quello inviato con il submit del form e lo elimina 
		 * dopo l'inserimento 
		 */
		if (!isTokenValid(request, false)) {
			return mapping.findForward("common.doublesubmit");
		}	
		
		DeviceForm deviceForm = (DeviceForm) actionForm;
		
		Device device = Device.getInstanceOf(deviceForm.getType());
		BeanUtils.copyProperties(device, deviceForm);
		
		Computer computer = (Computer) device.getComposite();
		if (computer != null) {
			for (Device hardware: deviceForm.getHardware()) {
				// A causa delle collection prepopolate in DeviceForm bisogna controllare...
				if (hardware.getModel()!=null) { // Non inserisce se il campo model è vuoto
					computer.addDevice(hardware);
				}
			}
			for (Device software: deviceForm.getSoftware()) {
				if (software.getModel()!=null) {
					computer.addDevice(software);
				}
			}
		}
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		
		service.updateDevice(device);
		
		// Rimozione del token dalla sessione
		resetToken(request);
		
		return mapping.findForward("common.ok");
	}
	
	public ActionForward activeadddevice(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		// Salvataggio del token riutilizzato nel metodo adddevice.
		saveToken(request);
		
		return mapping.findForward("operator.activeadddevice");
	}
	
	/* AJAX Request */
	public ActionForward adddevice(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		/* controlla se il token inserito in sessione dal metodo activeadddevice
		 * E' valido rispetto a quello inviato con il submit del form e lo elimina 
		 * dopo l'inserimento 
		 */
		if (!isTokenValid(request, false)) {
			return mapping.findForward("common.doublesubmit");
		}	
		
		DeviceForm deviceForm = (DeviceForm) actionForm;
		String deviceType = deviceForm.getType();
		Device device = Device.getInstanceOf(deviceType);
		
		BeanUtils.copyProperties(device, deviceForm);
		List<Device> softwareList = deviceForm.getSoftware();
		List<Device> hardwareList = deviceForm.getHardware();
		
		Computer computer = (Computer) device.getComposite();
		if (computer != null) {
			for (Device component: softwareList) {
				// A causa delle collection prepopolate in DeviceForm bisogna controllare...
				if (!"empty".equals(component.getModel())) {
					computer.addDevice(component); // Non inserisce se il campo model è vuoto
				}
			}
			for (Device component: hardwareList) {
				if (!"empty".equals(component.getModel())) {
					computer.addDevice(component);
				}
			}
		}
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		DeviceService service = factory.getDeviceService();
		
		service.addDevice(device);
		
		// Rimozione del token dalla sessione
		resetToken(request);
		
		return mapping.findForward("common.ok");
	}
}
